#include "SQLiteDatabase.h"
#include "../../common/CppMemPool.h"
#include "sqlite3.h"

namespace cppflib
{

namespace database
{

namespace sqlite
{

PRIVATE sqlite3* __GetDbConn(ptrany_t pDbConn)
{
   return static_cast<sqlite3*>(pDbConn);
}

SQLiteDatabase::SQLiteDatabase(void)
{
   this->pDbConn = NULL;
}

SQLiteDatabase::~SQLiteDatabase(void)
{
   Close();
}

/**
 *  Open database for read/write. Create it if not exists
 */
bool SQLiteDatabase::Open(const CFString &dbPath)
{
   if (dbPath.IsEmpty() || pDbConn != NULL)
      return false;

   sqlite3 *pConn = NULL;
//#if defined(WIN32)
   int ret = sqlite3_open16(static_cast<pcwstr_t>(dbPath), &pConn);
//#elif defined(linux)
//   char *pPath = dbPath.ToUtf8String();
//   int ret = sqlite3_open(pPath, &pConn);
//   cppmempool::Release(pPath);
//#endif

   if (ret != SQLITE_OK) {
      sqlite3_close(pConn);
   }
   else {     
      // assign finally
      this->pDbConn = static_cast<ptrany_t>(pConn);
      this->dbPath = dbPath;
   }

   return (ret == SQLITE_OK);
}

/**
 *  Close db connection
 */
void SQLiteDatabase::Close()
{
   if (pDbConn != NULL) {
      sqlite3_close(__GetDbConn(pDbConn));
      pDbConn = NULL;
   }
}

/**
 *  Return the connected database handle
 */
ptrany_t SQLiteDatabase::GetDbConn()
{
   return this->pDbConn;
}

/**
 *  Return the db path
 */
void SQLiteDatabase::GetDbPath(CFString &path)
{
   path = this->dbPath;
}

/**
 *  Get the most recent error message
 */
void SQLiteDatabase::GetDbLastError(CFString &err)
{
   CFString msg(sqlite3_errmsg(__GetDbConn(pDbConn)));
   err.Format(_S("msg: %s, err code = %d, extended err code = %d"), static_cast<pcwstr_t>(msg), 
                                                                    sqlite3_errcode(__GetDbConn(pDbConn)),
                                                                    sqlite3_extended_errcode(__GetDbConn(pDbConn)));
}

/**
 *  Get the row ID just after a 'INSERT' is performed
 */
i64_t SQLiteDatabase::GetLastInsertRowID()
{
   return sqlite3_last_insert_rowid(__GetDbConn(pDbConn));
}

/**
 *  Return version of the currently using SQLite library
 */
void SQLiteDatabase::GetSQLiteVersion(CFString &ver)
{
   ver = sqlite3_libversion();
}

pcwstr_t SQLiteDatabase::GetConstName(SQLiteDatabase::sqlitenames_t n)
{
   switch(n) {
      case SQLiteDatabase::ROWID: return _S("rowid");
      case SQLiteDatabase::MAINDB: return _S("main");
      case SQLiteDatabase::TEMPDB: return _S("temp");
   }

   return _S("");
}

const char * SQLiteDatabase::GetConstNameA(SQLiteDatabase::sqlitenames_t n)
{
   switch(n) {
      case SQLiteDatabase::ROWID: return "rowid";
      case SQLiteDatabase::MAINDB: return "main";
      case SQLiteDatabase::TEMPDB: return "temp";
   }

   return "";
}



} // end of namespace sqlite

} // end of namespace database

} // end of namespace cppflib

